/****************************************************************************
 *
 * Copyright (C) 2003-2008 Los Alamos National Security, LLC
 *                         Packet Analytics Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 2 as
 * published by the Free Software Foundation.  You may not use, modify or
 * distribute this program under any other version of the GNU General
 * Public License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 ****************************************************************************/
package nfse.query;

import java.util.*;

public class DateRange implements Comparable<DateRange> {
	private QueryDate startDate = null;
	private QueryDate endDate = null;
	

	public DateRange(QueryDate startDate) {
		this.startDate = startDate;
		this.endDate = startDate;
	}

	public DateRange(QueryDate startDate, QueryDate endDate) {
		this.startDate = startDate;
		this.endDate = endDate;
	}

	
	public int compareTo(DateRange dr) {
		try {
			if ((dr.getStartDate().compareTo(startDate) == 0) && (dr.getEndDate().compareTo(endDate) == 0))
				return 0;
		} catch (Exception E) {
			return -1;
		}
		if (dr.getStartDate().compareTo(startDate) > 0)
			return -1;
		if (dr.getStartDate().compareTo(startDate) < 0)
			return 1;
		return -1;
	}

	public boolean isRange() {
		if (endDate.compareTo(startDate) == 0)
			return false;
		return true;
	}

	public void extend(DateRange dr) {
		if (extendsEnd(dr))
			endDate = dr.getEndDate();
		if (extendsStart(dr))
			startDate = dr.startDate;
	}

	public boolean extendsEnd(DateRange dr) {
		return false;
	}

	public boolean extendsStart(DateRange dr) {
		return false;
	}

	public boolean contains(DateRange dr) {
		if (endDate == null) {
			if ((!dr.isRange()) && (dr.getStartDate().compareTo(startDate) == 0))
				return true;
			return false;
		}
		if ((dr.getStartDate().compareTo(startDate) >= 0) && (dr.getEndDate().compareTo(endDate) <= 0))
			return true;
		return false;
	}

	public void setStartDate(QueryDate startDate) {
		this.startDate = startDate;
		if (endDate == null)
			endDate = startDate;
	}

	public void setEndDate(QueryDate endDate) {
		this.endDate = endDate;
	}

	public QueryDate getStartDate() {
		return startDate;
	}

	public QueryDate getEndDate() {
		return endDate;
	}

	public QueryDate[] getDates() {
		Vector<QueryDate> temp = new Vector<QueryDate>();

		if ((this.endDate == null) || (this.endDate.compareTo(this.startDate) == 0))
			temp.addElement(this.startDate);
		else {
			GregorianCalendar c = (GregorianCalendar)Calendar.getInstance();
			c.set(Calendar.DAY_OF_MONTH, startDate.day);
			c.set(Calendar.MONTH, startDate.month);
			c.set(Calendar.YEAR, startDate.year);
			GregorianCalendar c2 = (GregorianCalendar)Calendar.getInstance();
			c2.set(Calendar.DAY_OF_MONTH, endDate.day);
			c2.set(Calendar.MONTH, endDate.month);
			c2.set(Calendar.YEAR, endDate.year);
			temp.addElement(startDate);
			while (c.getTime().getTime() != c2.getTime().getTime()) {
				c.add(Calendar.DAY_OF_MONTH, 1);	
				//System.out.println("added date " + c.getTime().toString());	
				temp.addElement(new QueryDate(c.get(Calendar.MONTH)+1, c.get(Calendar.DAY_OF_MONTH),c.get(Calendar.YEAR)));
			}
			
		}
		// Break range into day units, return results

		QueryDate[] dates = new QueryDate[temp.size()];
		for (int i = 0; i < dates.length; i++)
			dates[i] = (QueryDate) temp.elementAt(i);
		return dates;
	}

	public static DateRange[] consolidate(Vector<DateRange> dateRanges) {
		Vector<DateRange> temp = new Vector<DateRange>();
		Vector<QueryDate> temp2 = new Vector<QueryDate>();
		for (int i = 0; i < dateRanges.size(); i++) {
			//System.out.println("Getting dates...");
			QueryDate[] temp3 = ((DateRange) dateRanges.elementAt(i)).getDates();
			//System.out.println("...done.");
			for (int j = 0; j < temp3.length; j++) {
				//System.out.println("Adding " + temp3[j].toXML());
				temp2.addElement(temp3[j]);
			}
			temp3 = null;
		}
		QueryDate[] dates = new QueryDate[temp2.size()];
		for (int i = 0; i < dates.length; i++)
			dates[i] = (QueryDate) temp2.elementAt(i);
		//System.out.println("Sorting...");
		Arrays.sort(dates);
		//System.out.println("..done sorting.");

		int idx = 0;
		QueryDate current = null;
		while (idx < dates.length) {
			current = dates[idx];
			DateRange dateRange = new DateRange(current);
			idx++;
			while ((idx < dates.length) && (current.isNext(dates[idx]))) {
				current = dates[idx];
				dateRange.setEndDate(current);
				idx++;
			}
			if (idx+1 == dates.length)
				idx++;
			//System.out.println("Adding " + dateRange.toXML());
			temp.addElement(dateRange);
		} 
		
		DateRange[] ranges = new DateRange[temp.size()];
		for (int i = 0; i < ranges.length; i++)
			ranges[i] = (DateRange) temp.elementAt(i);
		temp = null;
		temp2 = null;	
		return ranges;
	}

	public String toXML() {
		String temp = "<Date ";
		temp += "start=\"" + startDate + "\"";
		if (endDate.compareTo(startDate) != 0)
			temp += " end=\"" + endDate + "\"";
		temp += "/>";
		return temp;
	}
	
	public String toString() {
		return toXML();	
	}
}